﻿//
// ParallelGrep
//
// Copyright (C) 2011 - Tatsuya Niioka
//
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Input;
using ParallelGrep.Model;
using ParallelGrep.Properties;
using System.Diagnostics;
using GrepEngine;
using System.Text.RegularExpressions;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.AvalonEdit.Document;
using ParallelGrep.Utility;
using ParallelGrep.IO;
using System.Windows.Media.Imaging;

namespace ParallelGrep.ViewModel
{
    /// <summary>
    /// 進捗状況ViewModel
    /// </summary>
    public class ProgressViewModel : ViewModel
    {
        private MainViewModel m_mainViewModel;

        #region IsRunner
        /// <summary>
        /// 実行中の状態を取得します。
        /// </summary>
        public bool IsRunner
        {
            get
            {
                return m_mainViewModel.IsRunner;
            }
        }
        #endregion

        #region IsEnabled
        /// <summary>
        /// 有効の状態を取得します。
        /// </summary>
        public bool IsEnabled
        {
            get
            {
                return m_mainViewModel.IsEnabled;
            }
        }
        #endregion

        #region Constructor
        /// <summary>
        /// 指定したMainViewModelで新しい<see cref="ProgressViewModel"/>クラスを生成します。
        /// </summary>
        /// <param name="mainViewModel">MainViewModel</param>
        public ProgressViewModel(MainViewModel mainViewModel)
        {
            m_mainViewModel = mainViewModel;
            LoadResources();
            LoadSendToFiles();
        }
        #endregion

        #region LoadResources
        /// <summary>
        /// リソース読み込み処理を実行します。
        /// </summary>
        public void LoadResources()
        {
            #region OutputStyles
            OutputStyles.Clear();
            OutputStyles.Add(new ItemInfo() { ID = "Csv", Name = Resources.OutputStyleCsv });
            OutputStyles.Add(new ItemInfo() { ID = "Tsv", Name = Resources.OutputStyleTsv });
            OutputStyles.Add(new ItemInfo() { ID = "Html", Name = Resources.OutputStyleHtml });

            OnPropertyChanged("OutputStyle");
            #endregion

            ProgressMenuPath.DisplayName = Resources.ProgressPath;
            ProgressMenuSize.DisplayName = Resources.ProgressSize;
            ProgressLineNumber.DisplayName = Resources.ProgressLineNumber;
            ProgressMenuColumnIndex.DisplayName = Resources.ProgressColumnIndex;
            ProgressMenuText.DisplayName = Resources.ProgressText;
            ProgressMenuEncoding.DisplayName = Resources.ProgressEncoding;
        }
        #endregion

        private MenuInfo<string> m_progressMenuFileName = null;
        /// <summary>
        /// コンテキストメニューを取得します。
        /// </summary>
        public MenuInfo<string> ProgressMenuFileName
        {
            get
            {
                if (m_progressMenuFileName == null)
                {
                    m_progressMenuFileName = new MenuInfo<string>(Resources.ProgressPath, null, null);
                    m_progressMenuFileName.IsChecked = true;
                }
                return m_progressMenuFileName;
            }
        }

        private MenuInfo<string> m_progressMenuPath = null;
        /// <summary>
        /// コンテキストメニューを取得します。
        /// </summary>
        public MenuInfo<string> ProgressMenuPath
        {
            get {
                if (m_progressMenuPath == null)
                {
                    m_progressMenuPath = new MenuInfo<string>(Resources.ProgressPath, null, null);
                    m_progressMenuPath.IsChecked = true;
                }
                return m_progressMenuPath; 
            }
        }
        private MenuInfo<string> m_progressMenuSize = null;
        /// <summary>
        /// コンテキストメニューを取得します。
        /// </summary>
        public MenuInfo<string> ProgressMenuSize
        {
            get {
                if (m_progressMenuSize == null)
                {
                    m_progressMenuSize = new MenuInfo<string>(Resources.ProgressSize, null,null);
                    m_progressMenuSize.IsChecked = true;
                }

                return m_progressMenuSize; 
            }
        }
        private MenuInfo<string> m_progressMenuLineNumber = null;
        /// <summary>
        /// コンテキストメニューを取得します。
        /// </summary>
        public MenuInfo<string> ProgressLineNumber
        {
            get {
                if (m_progressMenuLineNumber == null)
                {
                    m_progressMenuLineNumber = new MenuInfo<string>(Resources.ProgressLineNumber,null,null);
                    m_progressMenuLineNumber.IsChecked = true;
                }
                return m_progressMenuLineNumber;
            }
        }
        private MenuInfo<string> m_progressMenuColumnIndex = null;
        /// <summary>
        /// コンテキストメニューを取得します。
        /// </summary>
        public MenuInfo<string> ProgressMenuColumnIndex
        {
            get {
                if (m_progressMenuColumnIndex == null)
                {
                    m_progressMenuColumnIndex = new MenuInfo<string>(Resources.ProgressColumnIndex, null, null);
                    m_progressMenuColumnIndex.IsChecked = true;
                }
                return m_progressMenuColumnIndex; 
            }
        }
        private MenuInfo<string> m_progressMenuText = null;
        /// <summary>
        /// コンテキストメニューを取得します。
        /// </summary>
        public MenuInfo<string> ProgressMenuText
        {
            get {
                if (m_progressMenuText == null)
                {
                    m_progressMenuText = new MenuInfo<string>(Resources.ProgressText, null,null);
                    m_progressMenuText.IsChecked = true;
                }
                return m_progressMenuText; 
            }
        }
        private MenuInfo<string> m_progressMenuEncoding = null;
        /// <summary>
        /// コンテキストメニューを取得します。
        /// </summary>
        public MenuInfo<string> ProgressMenuEncoding
        {
            get {
                if (m_progressMenuEncoding == null)
                {
                    m_progressMenuEncoding = new MenuInfo<string>(Resources.ProgressEncoding, null,null);
                    m_progressMenuEncoding.IsChecked = true;
                }
                return m_progressMenuEncoding; 
            }
        }

        internal void AllPropertyChanged()
        {
            Clear();
        }

        #region SelectedProgress
        private ProgressInfo m_seletedProgress;
        /// <summary>
        /// 現在の進捗状況を取得または設定します。
        /// </summary>
        public ProgressInfo SeletedProgress
        {
            get { return m_seletedProgress; }
            set
            {
                m_seletedProgress = value;
                OnPropertyChanged("SeletedProgress");
            }
        }
        #endregion

        #region Progresses
        private ObservableCollection<ProgressInfo> m_progresses;
        /// <summary>
        /// 進捗状況を取得します。
        /// </summary>
        public ObservableCollection<ProgressInfo> Progresses
        {
            get
            {
                if (m_progresses == null)
                {
                    m_progresses = new ObservableCollection<ProgressInfo>();
                }
                return m_progresses;
            }
        }
        #endregion

        #region OutputStyle
        private OutputStyleMode m_outputStyle = OutputStyleMode.Tsv;
        /// <summary>
        /// 出力スタイルを取得または設定します。
        /// </summary>
        public string OutputStyle
        {
            get
            {
                return m_outputStyle.ToString();
            }
            set
            {
                OutputStyleMode mode;
                try
                {
                    mode = (OutputStyleMode)Enum.Parse(typeof(OutputStyleMode), value);
                }
                catch
                {
                    return;
                }
                if (m_outputStyle == mode)
                {
                    return;
                }
                m_outputStyle = mode;
                this.OnPropertyChanged("OutputStyle");
            }
        }
        #endregion

        #region OutputStyles
        private ObservableCollection<ItemInfo> m_outputStyles;
        /// <summary>
        /// 出力スタイル一覧を取得します。
        /// </summary>
        public ObservableCollection<ItemInfo> OutputStyles
        {
            get
            {
                if (m_outputStyles == null)
                {
                    m_outputStyles = new ObservableCollection<ItemInfo>();
                }
                return m_outputStyles;
            }
        }
        #endregion

        #region FileOutputCommand
        private RelayCommand m_fileOutputCommand;
        /// <summary>
        /// ファイル出力コマンドを取得します。
        /// </summary>
        public ICommand FileOutputCommand
        {
            get
            {
                if (m_fileOutputCommand == null)
                {
                    m_fileOutputCommand = new RelayCommand(param => this.FileOutput());
                }
                return m_fileOutputCommand;
            }
        }
        #endregion

        #region FileOutput
        /// <summary>
        /// ファイル出力を実行します。
        /// </summary>
        public void FileOutput()
        {
            var dialog = new System.Windows.Forms.SaveFileDialog();
            dialog.Filter = Resources.ProgressFileOutputFilter;
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                using (StreamWriter writer = new StreamWriter(dialog.FileName, false, Encoding.GetEncoding("Shift_JIS")))
                {
                    if (dialog.FilterIndex == 1)
                    {
                        ProgressWriter.WriteCsv(Progresses, writer);
                    }
                    else if (dialog.FilterIndex == 2)
                    {
                        ProgressWriter.WriteTab(Progresses, writer);
                    }
                    else if (dialog.FilterIndex == 3)
                    {
                        ProgressWriter.WriteHtml(Progresses, writer);
                    }
                }
            }
        }
        #endregion

        #region ClipboardOutputCommand
        private RelayCommand m_clipboardOutputCommand;
        /// <summary>
        /// クリップボード出力コマンドを取得します。
        /// </summary>
        public ICommand ClipboardOutputCommand
        {
            get
            {
                if (m_clipboardOutputCommand == null)
                {
                    m_clipboardOutputCommand = new RelayCommand(param => this.ClipboardOutput());
                }
                return m_clipboardOutputCommand;
            }
        }
        #endregion

        #region ClipboardOutput
        /// <summary>
        /// クリップボード出力を実行します。
        /// </summary>
        public void ClipboardOutput()
        {
            using (StringWriter writer = new StringWriter())
            {
                if (OutputStyle == "Csv")
                {
                    ProgressWriter.WriteCsv(Progresses, writer);
                }
                else if (OutputStyle == "Tsv")
                {
                    ProgressWriter.WriteTab(Progresses, writer);
                }
                else if (OutputStyle == "Html")
                {
                    ProgressWriter.WriteHtml(Progresses, writer);
                }
                Clipboard.SetText(writer.ToString());
            }
        }
        #endregion

        #region RunEditorOutputCommand
        private RelayCommand m_runEditorOutputCommand;
        /// <summary>
        /// エディタ起動コマンドを取得します。
        /// </summary>
        public ICommand RunEditorOutputCommand
        {
            get
            {
                if (m_runEditorOutputCommand == null)
                {
                    m_runEditorOutputCommand = new RelayCommand(param => this.RunEditor());
                }
                return m_runEditorOutputCommand;
            }
        }
        #endregion

        #region EditorOutput
        /// <summary>
        /// エディタ起動を実行します。
        /// </summary>
        public void RunEditor()
        {
            string programFile = RegistryHelper.GetEditorProgram();
            string path = System.IO.Path.GetTempFileName();
            using (StreamWriter writer = new StreamWriter(path, false, Encoding.GetEncoding("Shift_JIS")))
            {
                if (OutputStyle == "Csv")
                {
                    ProgressWriter.WriteCsv(Progresses, writer);
                }
                else if (OutputStyle == "Tsv")
                {
                    ProgressWriter.WriteTab(Progresses, writer);
                }
                else if (OutputStyle == "Html")
                {
                    ProgressWriter.WriteHtml(Progresses, writer);
                }
            }
            string[] args = StringHelper.Split(programFile);
            ProcessStartInfo info = new ProcessStartInfo(args[0], path);
            System.Diagnostics.Process.Start(info); // Editor selectCulture
        }
        #endregion

        #region Clear
        /// <summary>
        /// 進行状況をクリアします。
        /// </summary>
        internal void Clear()
        {
            Progresses.Clear();
            IsOpration = false;
        }
        #endregion

        #region Add
        /// <summary>
        /// 指定した進行状況を追加します。
        /// </summary>
        /// <param name="info">進行状況</param>
        internal void Add(ProgressInfo info)
        {
            Progresses.Add(info);
            IsOpration = true;
        }
        #endregion

        #region Document
        private TextDocument m_document;
        /// <summary>
        /// ドキュメントを取得または設定します。
        /// </summary>
        public TextDocument Document
        {
            get { return m_document; }
            set
            {
                if (m_document == value)
                {
                    return;
                }
                m_document = value;
                OnPropertyChanged("Document");
            }
        }
        #endregion

        #region HighlightingDefinition
        private IHighlightingDefinition m_highlightingDefinition = null;
        /// <summary>
        /// テキストエディタのハイライトを取得または設定します。
        /// </summary>
        public IHighlightingDefinition HighlightingDefinition
        {
            get
            {
                return m_highlightingDefinition;
            }
            set
            {
                if (m_highlightingDefinition != null)
                {
                    if (m_highlightingDefinition.Name == value.Name)
                    {
                        return;
                    }
                }
                m_highlightingDefinition = value;
                OnPropertyChanged("HighlightingDefinition");
            }
        }
        #endregion

        #region ColumnIndex
        private int m_columnIndex;
        /// <summary>
        /// カラム位置を取得または設定します。
        /// </summary>
        public int ColumnIndex
        {
            get
            {
                return m_columnIndex;
            }
            set
            {
                if (m_columnIndex == value)
                {
                    return;
                }
                m_columnIndex = value;
                OnPropertyChanged("ColumnIndex");
            }
        }
        #endregion

        #region LineNumber
        private int m_lineNumber;
        /// <summary>
        /// 行番号を取得または設定します。
        /// </summary>
        public int LineNumber
        {
            get
            {
                return m_lineNumber;
            }
            set
            {
                if (m_lineNumber == value)
                {
                    return;
                }
                m_lineNumber = value;
                OnPropertyChanged("LineNumber");
            }
        }
        #endregion

        #region VisualLineTransformer
        private IVisualLineTransformer m_visualLineTransformer;
        /// <summary>
        /// ビジュアルライントランスファーを取得または設定します。
        /// </summary>
        public IVisualLineTransformer VisualLineTransformer
        {
            get
            {
                return m_visualLineTransformer;
            }
            set
            {
                m_visualLineTransformer = value;
                OnPropertyChanged("VisualLineTransformer");
            }
        }
        #endregion

        #region ListSelectionChanged
        private string m_saveFileName = null;
        private int m_saveLineNumber = 0;
        private int m_saveColumnIndex = 0;
        private Regex m_saveRegex = null;
        private string m_fileExtension = null;

        /// <summary>
        /// 進捗状況選択変更時処理
        /// </summary>
        public void ListSelectionChanged()
        {
            if (SeletedProgress == null)
            {
                Document = null;
            }
            else
            {
                if (m_saveFileName != SeletedProgress.FullName ||
                    m_saveLineNumber != SeletedProgress.LineNumber ||
                    m_saveColumnIndex != SeletedProgress.ColumnIndex)
                {
                    if (m_saveFileName != SeletedProgress.FullName)
                    {
                        Encoding encoding = FileHelper.GetEncoding(SeletedProgress.FullName);
                        if (encoding == null)
                        {
                            encoding = Encoding.UTF8;
                        }
                        string content = File.ReadAllText(SeletedProgress.FullName, encoding);
                        Document = new TextDocument(content);
                    }
                    if (m_saveLineNumber != SeletedProgress.LineNumber)
                    {
                        LineNumber = SeletedProgress.LineNumber;
                    }
                    if (m_saveColumnIndex != SeletedProgress.ColumnIndex)
                    {
                        ColumnIndex = SeletedProgress.ColumnIndex;
                    }
                    if (m_mainViewModel.Process == GrepMode.Grep.ToString() ||
                        m_mainViewModel.Process == GrepMode.Replace.ToString() ||
                        m_mainViewModel.Process == GrepMode.Delete.ToString())
                    {
                        Regex regex = Grep.GetRegex(m_mainViewModel.SearchValue,
                                                    m_mainViewModel.IsWord,
                                                    m_mainViewModel.IsIgnoreCase,
                                                    m_mainViewModel.IsConditions,
                                                    (ConditionsMode)Enum.Parse(typeof(ConditionsMode), m_mainViewModel.ConditionsMode));
                        if (m_saveRegex == null ||
                            m_saveRegex.ToString() != regex.ToString() ||
                            m_saveRegex.Options != regex.Options)
                        {
                            VisualLineTransformer = new RegexDocumentColorizingTransformer(regex);
                        }
                        if (m_fileExtension != Path.GetExtension(SeletedProgress.FullName))
                        {
                            HighlightingDefinition = HighlightingManager.Instance.GetDefinitionByExtension(System.IO.Path.GetExtension(SeletedProgress.FullName));
                        }
                        m_saveRegex = regex;
                    }
                    m_saveFileName = SeletedProgress.FullName;
                    m_lineNumber = LineNumber;
                    m_saveColumnIndex = ColumnIndex;
                    m_fileExtension = Path.GetExtension(SeletedProgress.FullName);
                }
            }
        }
        #endregion

        #region IsOpration
        private bool m_isOperation = false;
        /// <summary>
        /// オペレーション有無を取得します。
        /// </summary>
        public bool IsOpration
        {
            get
            {
                return m_isOperation;
            }
            set
            {
                if (m_isOperation == value)
                {
                    return;
                }
                m_isOperation = value;
                OnPropertyChanged("IsOpration");
            }
        }
        #endregion

        #region FileOpenCommand
        private RelayCommand m_fileOpenCommand;
        /// <summary>
        /// ファイルのオープン実行コマンドを取得します。
        /// </summary>
        public RelayCommand FileOpenCommand
        {
            get
            {
                if (m_fileOpenCommand == null)
                {
                    m_fileOpenCommand = new RelayCommand(param => this.FileOpen());
                }
                return m_fileOpenCommand;
            }
        }
        /// <summary>
        /// ファイルのオープンを実行します。
        /// </summary>
        public void FileOpen()
        {
            if (SeletedProgress != null)
            {
                if (IsOpen)
                {
                    string command = OpenProgram.Replace("%1", SeletedProgress.FullName);
                    string[] cmd = StringHelper.Split(command);
                    Process.Start(cmd[0], cmd[1]);
                }
            }
        }
        #endregion

        #region OpenWithCommand
        private RelayCommand m_openWidhCommand;
        /// <summary>
        /// ファイルを開くコマンドを取得します。
        /// </summary>
        public RelayCommand OpenWithCommand
        {
            get
            {
                if (m_openWidhCommand == null)
                {
                    m_openWidhCommand = new RelayCommand(param => FileOpenWidh(param));
                }
                return m_openWidhCommand;
            }
        }
        /// <summary>
        /// ファイルを開くコマンドを実行します。
        /// </summary>
        public void FileOpenWidh(object parameter)
        {
            if (SeletedProgress != null)
            {
                string value = (string)parameter;
                if (!string.IsNullOrWhiteSpace(value))
                {
                    string command = value.Replace("%1", SeletedProgress.FullName);
                    string[] cmd = StringHelper.Split(command);
                    Process.Start(cmd[0], cmd[1]);
                }
            }
        }
        #endregion

        #region ContextOpened
        /// <summary>
        /// コンテキストをオープン時に実行します。
        /// </summary>
        public void ContextOpened()
        {
            if (SeletedProgress != null)
            {
                OpenProgram = RegistryHelper.GetOpenProgram(SeletedProgress.FileName);
                EditProgram = RegistryHelper.GetEditProgram(SeletedProgress.FileName);

                OpenWithLists.Clear();
                MenuInfo<string>[] lists = RegistryHelper.GetOpenWithList(SeletedProgress.FileName);
                foreach (var menu in lists)
                {
                    OpenWithLists.Add(menu);
                }
                IsOpenWith = OpenWithLists.Count > 0;
                //IsContextMenu = true;
            }
            else
            {
                //IsContextMenu = false;
            }
        }
        #endregion

        ////#region IsContextMenu
        ////private bool m_isContextMenu = false;
        /////// <summary>
        /////// コンテキストメニュー表示有無を取得または設定します。
        /////// </summary>
        ////public bool IsContextMenu
        ////{
        ////    get
        ////    {
        ////        return m_isContextMenu;
        ////    }
        ////    set
        ////    {
        ////        if (m_isContextMenu == value)
        ////        {
        ////            return;
        ////        }
        ////        m_isContextMenu = value;
        ////        OnPropertyChanged("IsContextMenu");
        ////    }
        ////}
        ////#endregion

        #region VisibleProgressItems
        private ObservableCollection<MenuInfo<string>> m_visibleProgressItems;
        /// <summary>
        /// 表示項目のリストを取得します。
        /// </summary>
        public ObservableCollection<MenuInfo<string>> VisibleProgressItems
        {
            get
            {
                if (m_visibleProgressItems == null)
                {
                    m_visibleProgressItems = new ObservableCollection<MenuInfo<string>>();
                    m_visibleProgressItems.Add(ProgressMenuPath);
                    m_visibleProgressItems.Add(ProgressMenuSize);
                    m_visibleProgressItems.Add(ProgressLineNumber);
                    m_visibleProgressItems.Add(ProgressMenuColumnIndex);
                    m_visibleProgressItems.Add(ProgressMenuText);
                    m_visibleProgressItems.Add(ProgressMenuEncoding);
                }
                return m_visibleProgressItems;
            }
        }
        #endregion


        #region OpenProgram
        private string m_openProgram = null;
        /// <summary>
        /// ファイルを開くプログラムを取得または設定します。
        /// </summary>
        public string OpenProgram
        {
            get
            {
                return m_openProgram;
            }
            set
            {
                if (m_openProgram == value)
                {
                    return;
                }
                m_openProgram = value;
                OnPropertyChanged("OpenProgram");
                if (string.IsNullOrEmpty(value))
                {
                    IsOpen = false;
                }
                else
                {
                    IsOpen = true;
                }
            }
        }
        #endregion

        #region IsOpen
        private bool m_isOpen = false;  // Context IsOpen
        /// <summary>
        /// ファイルを開く表示有無を取得または設定します。
        /// </summary>
        public bool IsOpen
        {
            get
            {
                return m_isOpen;
            }
            set
            {
                if (m_isOpen == value)
                {
                    return;
                }
                m_isOpen = value;
                OnPropertyChanged("IsOpen");
            }
        }
        #endregion

        #region EditProgram
        private string m_editProgram = null;
        /// <summary>
        /// ファイルを編集プログラムを取得または設定します。
        /// </summary>
        public string EditProgram
        {
            get
            {
                return m_editProgram;
            }
            set
            {
                if (m_editProgram == value)
                {
                    return;
                }
                m_editProgram = value;
                OnPropertyChanged("EditProgram");
                if (string.IsNullOrEmpty(value))
                {
                    IsEdit = false;
                }
                else
                {
                    IsEdit = true;
                }
            }
        }
        #endregion

        #region IsEdit
        private bool m_isEdit = false;  // Context IsEdit
        /// <summary>
        /// ファイルを編集表示有無を取得または設定します。
        /// </summary>
        public bool IsEdit
        {
            get
            {
                return m_isEdit;
            }
            set
            {
                if (m_isEdit == value)
                {
                    return;
                }
                m_isEdit = value;
                OnPropertyChanged("IsEdit");
            }
        }
        #endregion

        #region OpenWithLists
        private ObservableCollection<MenuInfo<string>> m_openWithLists;
        /// <summary>
        /// ファイルを開くのプログラムリストを取得します。
        /// </summary>
        public ObservableCollection<MenuInfo<string>> OpenWithLists
        {
            get
            {
                if (m_openWithLists == null)
                {
                    m_openWithLists = new ObservableCollection<MenuInfo<string>>();
                }
                return m_openWithLists;
            }
        }
        #endregion

        #region IsOpenWith
        private bool m_isOpenWith = false;
        /// <summary>
        /// ファイルを開く表示有無を取得または設定します。
        /// </summary>
        public bool IsOpenWith
        {
            get
            {
                return m_isOpenWith;
            }
            set
            {
                if (m_isOpenWith == value)
                {
                    return;
                }
                m_isOpenWith = value;
                OnPropertyChanged("IsOpenWith");
            }
        }
        #endregion

        #region FileEditCommand
        private RelayCommand m_fileEditCommand;
        /// <summary>
        /// ファイルの編集コマンドを取得します。
        /// </summary>
        public RelayCommand FileEditCommand
        {
            get
            {
                if (m_fileEditCommand == null)
                {
                    m_fileEditCommand = new RelayCommand(param => this.FileEdit());
                }
                return m_fileEditCommand;
            }
        }
        /// <summary>
        /// 編集を実行します。
        /// </summary>
        private void FileEdit()
        {
            if (SeletedProgress != null)
            {
                if (IsEdit)
                {
                    string command = EditProgram.Replace("%1", SeletedProgress.FullName);
                    string[] cmd = StringHelper.Split(command);
                    Process.Start(cmd[0], cmd[1]);
                }
            }
        }
        #endregion

        #region FileDeleteCommand
        private RelayCommand m_fileDeleteCommand;
        /// <summary>
        /// ファイルの削除コマンドを取得します。
        /// </summary>
        public RelayCommand FileDeleteCommand
        {
            get
            {
                if (m_fileDeleteCommand == null)
                {
                    m_fileDeleteCommand = new RelayCommand(param => this.FileDelete());
                }
                return m_fileDeleteCommand;
            }
        }
        /// <summary>
        /// ファイルを削除します。
        /// </summary>
        private void FileDelete()
        {
            if (SeletedProgress != null)
            {
                if (MessageBox.Show(Resources.FileDeleteConfirm,
                                    Resources.FileDeleteConfirmTitle,
                                    MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                {
                    File.Delete(SeletedProgress.FullName);
                }
            }
        }
        #endregion

        #region FileCutCommand
        private RelayCommand m_fileCutCommand;
        /// <summary>
        /// ファイルカットの実行コマンドを取得します。
        /// </summary>
        public RelayCommand FileCutCommand
        {
            get
            {
                if (m_fileCutCommand == null)
                {
                    m_fileCutCommand = new RelayCommand(param => this.FileCut());
                }
                return m_fileCutCommand;
            }
        }
        /// <summary>
        /// ファイルカットを実行します。
        /// </summary>
        private void FileCut()
        {
            if (SeletedProgress != null)
            {
                IDataObject data = new DataObject(DataFormats.FileDrop, new string[] { SeletedProgress.FullName });
                byte[] bs = new byte[] { (byte)DragDropEffects.Move, 0, 0, 0 };
                System.IO.MemoryStream ms = new System.IO.MemoryStream(bs);
                data.SetData("Preferred DropEffect", ms);

                Clipboard.SetDataObject(data);
            }
        }
        #endregion

        #region FileCopyCommand
        private RelayCommand m_fileCopyCommand;
        /// <summary>
        /// ファイルコピーの実行コマンドを取得します。
        /// </summary>
        public RelayCommand FileCopyCommand
        {
            get
            {
                if (m_fileCopyCommand == null)
                {
                    m_fileCopyCommand = new RelayCommand(param => this.FileCopy());
                }
                return m_fileCopyCommand;
            }
        }
        /// <summary>
        /// ファイルコピーを実行します。
        /// </summary>
        private void FileCopy()
        {
            if (SeletedProgress != null)
            {
                IDataObject data = new DataObject(DataFormats.FileDrop, new string[] { SeletedProgress.FullName });
                Clipboard.SetDataObject(data);
            }
        }
        #endregion

        #region FileNameCopyCommand
        private RelayCommand m_fileNameCopyCommand;
        /// <summary>
        /// ファイル名をコピーコマンドを取得します。
        /// </summary>
        public ICommand FileNameCopyCommand
        {
            get
            {
                if (m_fileNameCopyCommand == null)
                {
                    m_fileNameCopyCommand = new RelayCommand(param => this.FileNameCopyExecute());
                }
                return m_fileNameCopyCommand;
            }
        }
        /// <summary>
        /// ファイル名をコピーを実行します。
        /// </summary>
        public void FileNameCopyExecute()
        {
            if (SeletedProgress != null)
            {
                Clipboard.SetText(SeletedProgress.FileName);
            }
        }
        #endregion

        #region FullNameCopyCommand
        private RelayCommand m_fullNameCopyCommand;
        /// <summary>
        /// ファイルパスをコピーコマンドを取得します。
        /// </summary>
        public ICommand FullNameCopyCommand
        {
            get
            {
                if (m_fullNameCopyCommand == null)
                {
                    m_fullNameCopyCommand = new RelayCommand(param => this.FullNameCopyExecute());
                }
                return m_fullNameCopyCommand;
            }
        }
        /// <summary>
        /// ファイルパスをコピーを実行します。
        /// </summary>
        private void FullNameCopyExecute()
        {
            if (SeletedProgress != null)
            {
                Clipboard.SetText(SeletedProgress.FullName);
            }
        }
        #endregion

        #region OpenFolderCommand
        private RelayCommand m_openFolderCommand;
        /// <summary>
        /// エクスプローラーでフォルダを開くコマンドを取得します。
        /// </summary>
        public ICommand OpenFolderCommand
        {
            get
            {
                if (m_openFolderCommand == null)
                {
                    m_openFolderCommand = new RelayCommand(param => this.OpenFolderExecute());
                }
                return m_openFolderCommand;
            }
        }
        /// <summary>
        /// エクスプローラーでフォルダを開くを実行します。
        /// </summary>
        private void OpenFolderExecute()
        {
            if (SeletedProgress != null)
            {
                Process.Start("explorer", SeletedProgress.Path);
            }
        }
        #endregion

        #region SendToCommand
        private RelayCommand m_sendToCommand;
        /// <summary>
        /// 送るコマンドを取得します。
        /// </summary>
        public RelayCommand SendToCommand
        {
            get
            {
                if (m_sendToCommand == null)
                {
                    m_sendToCommand = new RelayCommand(param => SendTo(param));
                }
                return m_sendToCommand;
            }
        }
        /// <summary>
        /// 指定したパラメータで送るを実行します。
        /// </summary>
        /// <param name="parameters">パラメータ</param>
        public void SendTo(object parameters)
        {
            if (SeletedProgress != null)
            {
                string target = (string)parameters;
                ProcessStartInfo info = new ProcessStartInfo(target, SeletedProgress.FullName);
                Process.Start(info);
            }
        }
        #endregion

        #region FileCreateShortCutCommand
        private RelayCommand m_fileCreateShortCutCommand;
        /// <summary>
        /// ファイルのショートカット作成コマンドを取得します。
        /// </summary>
        public RelayCommand FileCreateShortCutCommand
        {
            get
            {
                if (m_fileCreateShortCutCommand == null)
                {
                    m_fileCreateShortCutCommand = new RelayCommand(param => this.FileCreateShortCut());
                }
                return m_fileCreateShortCutCommand;
            }
        }
        /// <summary>
        /// ファイルのショートカットを作成します。
        /// </summary>
        public void FileCreateShortCut()
        {
            if (SeletedProgress != null)
            {
                ShortCutHelper.CreateDesktop(SeletedProgress.FullName);
            }
        }
        #endregion

        #region FilePropertiesCommand
        private RelayCommand m_filePropertiesCommand;
        /// <summary>
        /// ファイルプロパティ表示の実行コマンドを取得します。
        /// </summary>
        public RelayCommand FilePropertiesCommand
        {
            get
            {
                if (m_filePropertiesCommand == null)
                {
                    m_filePropertiesCommand = new RelayCommand(param => this.FileProperties());
                }
                return m_filePropertiesCommand;
            }
        }
        /// <summary>
        /// ファイルプロパティ表示を実行します。
        /// </summary>
        private void FileProperties()
        {
            if (SeletedProgress != null)
            {
                FilePropertiesDialog.ShowDialog(SeletedProgress.FullName);
            }
        }
        #endregion

        #region SendToFiles
        private ObservableCollection<MenuInfo<string>> m_sendToFiles;
        /// <summary>
        /// 送るファイル先一覧を取得します。
        /// </summary>
        public ObservableCollection<MenuInfo<string>> SendToFiles
        {
            get
            {
                if (m_sendToFiles == null)
                {
                    m_sendToFiles = new ObservableCollection<MenuInfo<string>>();
                }
                return m_sendToFiles;
            }
        }
        #endregion

        #region LoadSendToFiles
        /// <summary>
        /// 送信先ファイル読み込みを実行します。
        /// </summary>
        public void LoadSendToFiles()
        {
            // Send To
            string folder = Environment.GetFolderPath(Environment.SpecialFolder.SendTo);
            IEnumerable<string> files = Directory.EnumerateFiles(folder);
            foreach (string file in files)
            {
                FileInfo info = new FileInfo(file);
                if (info.Exists)
                {
                    System.Drawing.Icon icon = ExtractIcon.GetIcon(file, true);

                    BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                                                   icon.Handle, Int32Rect.Empty,
                                                   BitmapSizeOptions.FromEmptyOptions());

                    string title = info.Name.Replace(info.Extension, string.Empty);
                    MenuInfo<string> sendToFile = new MenuInfo<string>(title, info.FullName, bitmapSource);
                    SendToFiles.Add(sendToFile);
                }
            }
            // ドライブ
            string[] drives = Environment.GetLogicalDrives();
            foreach (string drive in drives)
            {
                DriveInfo info = new DriveInfo(drive);
                if (info.IsReady)
                {
                    System.Drawing.Icon icon = ExtractIcon.GetIcon(drive, true);
                    BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                                                   icon.Handle, Int32Rect.Empty,
                                                   BitmapSizeOptions.FromEmptyOptions());
                    MenuInfo<string> sendToFile = new MenuInfo<string>(info.Name, info.Name, bitmapSource);
                    SendToFiles.Add(sendToFile);
                }
            }
        }


        #endregion

        #region TextEditorCopyCommand
        private RelayCommand m_textEditorCopyCommand;
        /// <summary>
        /// テキストエディタコピーコマンドを取得します。
        /// </summary>
        public RelayCommand TextEditorCopyCommand
        {
            get
            {
                if (m_textEditorCopyCommand == null)
                {
                    m_textEditorCopyCommand = new RelayCommand(param => this.TextEditorCopy(param));
                }
                return m_textEditorCopyCommand;
            }
        }        
        /// <summary>
        /// 指定したパラメータで、テキストエディタコピーを実行します。
        /// </summary>
        /// <param name="parameter">パラメータ</param>
        public void TextEditorCopy(object parameter)
        {
            string value = (string)parameter;
            if (value != null)
            {
                Clipboard.SetText(value);
            }
        }
        #endregion

        #region TextEditorSearchPatternCommand
        private RelayCommand m_textEditorSearchPatternCommand;
        /// <summary>
        /// テキストエディタパターンコピーコマンドを取得します。
        /// </summary>
        public RelayCommand TextEditorSearchPatternCommand
        {
            get
            {
                if (m_textEditorSearchPatternCommand == null)
                {
                    m_textEditorSearchPatternCommand = new RelayCommand(param => this.TextEditorSearchPattern(param));
                }
                return m_textEditorSearchPatternCommand;
            }
        }
        /// <summary>
        /// テキストエディタパターンコピーを実行します。
        /// </summary>
        /// <param name="parameter">パラメータ</param>
        public void TextEditorSearchPattern(object parameter)
        {
            string value = (string)parameter;
            if (value != null)
            {
                bool isControl = false;
                foreach (char c in value)
                {
                    if (char.IsControl(c))
                    {
                        isControl = true;
                        break;
                    }
                }
                if (isControl)
                {
                    m_mainViewModel.SearchValue = Regex.Escape(value);
                    m_mainViewModel.IsConditions = true;
                    m_mainViewModel.ConditionsMode = ConditionsMode.Regex.ToString();
                }
                else
                {
                    m_mainViewModel.SearchValue = value;
                    m_mainViewModel.IsConditions = false;
                }
            }
        }
        #endregion
    }
}
